/**
 *
 */
package src.model.gameObject;

import src.model.gameObject.ability.*;

import java.util.Vector;

/**
 * <b>Overview</b><br>
 * <p>These are the standard objects that exist in the game. Anything on the map is a GameObject, including terrain,
 * Items, Units, Structures, etc. GameObjects have no game type abilities on their own, rather, they have a collection
 * of Ability Objects that handle all of the behaviors, mostly through events. It is defined by a GameObjectType (structure,
 * terrain, item, etc.) and a GameObjectSubtype (Corsair, factory, mountain, etc.).</p>
 * <br><br>
 * <b>Responsibilites</b><br>
 * <p>Encapsulate a GameObject. Manage its Abilities</p>
 * <br><br>
 * <b>Collaborators</b>
 * <br>Ability - all of the abilities that it knows<br>
 * <b>Implementor</b> - Tristan Lohman<br>
 * <b>Tester</b> - Brent<br>
 * @author Tristan
 *
 */
public class GameObject implements Cloneable {

	private GameObjectType type;
	private GameObjectSubtype subType;
	private Vector<Ability> ability;
	
	/**
	 * Create a new GameObject
	 * @param type The type of GameObject (unit, structure, terrain, etc.).
	 * @param subType The subtype (corsair, mountain, trap, etc.).
	 */
	public GameObject(GameObjectType type, GameObjectSubtype subType){
		this.type = type;
		this.subType = subType;
		ability = new Vector<Ability>();
	}
	
	/**
	 * 
	 * @return The GameObjectSubtype.
	 */
	public GameObjectSubtype getSubtype()
	{
		return subType;
	}

	/**
	 * 
	 * @return The GameObjectType.
	 */
	public GameObjectType getType()
	{
		return type;
	}

	/**'
	 * Adds a new ability to the GameObjects ability collection
	 * @param newAbil The instance of the new ability to be added.
	 */
	public void addAbility(Ability newAbil){
		ability.add(newAbil);
	}

	/**
	 * Adds a collection of Abilities to the Ability collection.
	 * @param newAbils The collection of new abilities to add.
	 */
	public void addAllAbility(Vector<Ability> newAbils){
		ability.addAll(newAbils);
	}
	
	/**
	 * 
	 * @return The collection of abilities.
	 */
	public Vector<Ability> getAbilities(){
		return ability;
	}
	
	public GameObject clone(){
		GameObject cloner = new GameObject(type, subType);
		cloner.addAllAbility(ability);
		return cloner;
	}
	
	/**
	 * Return the first instance of Ability with the specified AbilityType that
	 * is held in the GameObject's Ability collection
	 * @param type The type of ability to find.
	 * @return  The first instance of the desired ability.
	 */
	public Ability getAbility(AbilityType type){
		for (Ability a:ability){
			AbilityType thisType = a.abilityType();
			if (thisType == type) return a;
		}
		return null;
	}
	
	/**
	 * Remove a specific instance of an Ability from the ability list.
	 * @param removeMe The instance of ability to remove from the list.
	 */
	public void removeAbility(Ability removeMe){
		ability.remove(removeMe);
	}
}
